package org.xlp.db.bridge.strategy;

import org.xlp.db.sql.limit.Limit;
import org.xlp.db.xml.XmlSQL;
import org.xlp.db.xml.XmlSQLConstructorUtils;
import org.xlp.db.xml.ele.SQLEle;
import org.xlp.javabean.annotation.Bean;
import org.xlp.utils.XLPArrayUtil;

import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * Description: (Object[] params, Map<String, Object> map, B obj) : sql语句配置文件的预处理参数（参数列表顺序可变，但不能缺失）
 * <br/>date: 2024/4/23
 *
 * @version 1.0
 * @author: xlp
 */
public class OMBXmlSQLConstructorStrategy extends AbstractXmlSQLConstructorStrategy {
    /**
     * 构造函数
     */
    public OMBXmlSQLConstructorStrategy(){
       setWeight(1);
    }

    /**
     * 根据给定的参数类型获取相应的{@link XmlSQL}的构造函数
     *
     * @param methodReturnType
     * @param parameterClasses
     * @return
     */
    @Override
    public XmlSQLConstructorInfo getXmlSQLConstructor(Type methodReturnType,
                                    Class<?>[] parameterClasses, Object[] parameters) {
        if (XLPArrayUtil.isEmpty(parameterClasses)) return null;
        //匹配参数
        int index = Finder.findClassInClasses(parameterClasses, Object[].class);
        if (index == Finder.NOT_FIND) return null;
        List<Object> _parameters = new ArrayList<>();
        _parameters.add(parameters[index]);

        //获取实体类型
        Class<?> beanClass = getBeanClassByReturnType(methodReturnType);
        _parameters.add(beanClass);

        //匹配下一个参数
        index = Finder.findClassInClasses(parameterClasses, Map.class);
        if (index == Finder.NOT_FIND) {
            _parameters.add(null);
        } else {
            _parameters.add(parameters[index]);
        }

        //匹配下一个参数
        index = Finder.findAnnotationInClasses(parameterClasses, Bean.class);
        if (index == Finder.NOT_FIND) {
            _parameters.add(null);
        } else {
            _parameters.add(parameters[index]);
        }

        Class<?>[] classes = {SQLEle.class, Object[].class, Class.class, Map.class, Object.class};
        XmlSQLConstructorInfo info = new XmlSQLConstructorInfo();
        info.setParameters(_parameters);
        try {
            info.setConstructor(XmlSQLConstructorUtils.getXmlSQLConstructor(classes));
        } catch (NoSuchMethodException e) {
            throw new RuntimeException(e);
        }

        index = Finder.findClassInClasses(parameterClasses, Limit.class);
        if (index != Finder.NOT_FIND) info.setLimit((Limit) parameters[index]);
        return info;
    }
}
